home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume4 / fcpio < prev    next >
Encoding:
Text File  |  1989-02-03  |  8.4 KB  |  391 lines

  1. Path: xanth!mcnc!gatech!ukma!cwjcc!hal!ncoast!allbery
  2. From: joe@dayton.DHDSC.MN.ORG (Joseph P. Larson)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i118: fcpio - a fast cpio partial replacement
  5. Message-ID: <8810050954.AA27269@dayton.DHDSC.MN.ORG>
  6. Date: 7 Oct 88 00:16:54 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: joe@dayton.DHDSC.MN.ORG (Joseph P. Larson)
  9. Lines: 379
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 118
  13. Submitted-by: "Joseph P. Larson" <joe@dayton.DHDSC.MN.ORG>
  14. Archive-name: fcpio
  15.  
  16. In any case, I wrote up the enclosed program one day when I got a little
  17. too annoyed with cpio while dealing with some rather large cpio archives.
  18. It doesn't need a makefile (I just say make fcpio).  The two include files
  19. are from our <dayton/> directory, so people will need to patch the .c a
  20. little to specify where these came from.  (They AREN'T replacements for
  21. the regular includes of the same name!)
  22.  
  23. Hope someone finds this useful.  -Joe
  24.  
  25.  
  26. ----Cut Here----
  27.  
  28. #! /bin/sh
  29. # This is a shell archive, meaning:
  30. # 1. Remove everything above the #! /bin/sh line.
  31. # 2. Save the resulting text in a file.
  32. # 3. Execute the file with /bin/sh (not csh) to create:
  33. #    fcpio.doc
  34. #    fcpio.c
  35. #    math.h
  36. #    stdtyp.h
  37. # This archive created: Wed Oct  5 09:54:01 1988
  38. export PATH; PATH=/bin:/usr/bin:$PATH
  39. if test -f 'fcpio.doc'
  40. then
  41.     echo shar: "will not over-write existing file 'fcpio.doc'"
  42. else
  43. cat << \SHAR_EOF > 'fcpio.doc'
  44. PROGRAM:
  45.  
  46.     fcpio -- a fast cpio for seekable devices
  47.  
  48.  
  49. SYNOPSIS:
  50.  
  51.     fcpio [-options] archive-name [extract-pattern1 [ ... extract-patternn]]
  52.  
  53.     Options implemented to date:
  54.  
  55.         x - extract files
  56.         t - table of contents
  57.  
  58.  
  59. DESCRIPTION:
  60.  
  61.     fcpio is a partial cpio (tm Ma Bell) replacement.  It is very useful
  62.     when performing extracts or retrieving a table of contents from a
  63.     disk-resident cpio archive.  This is due to use of seeks to skip over
  64.     unwanted data.  (Our copy of cpio reads through everything as it must
  65.     assume it can't seek.)  Thus, a -t on a 3.3 Meg file runs at output
  66.     (9600 baud) speeds with fcpio but has long pauses with cpio at all the
  67.     long (> 20K) files within the archive.  An extract of a few items is
  68.     also very fast.
  69.  
  70.     The extract patterns do not support wild carding or anything fancy --
  71.     fcpio will extract any files that begin with one of the extract patterns
  72.     (or all files if no extract pattern is specified).
  73.  
  74.  
  75. AUTHOR:
  76.  
  77.     Joe Larson
  78.     Dayton-Hudson Department Store Company
  79.     700 On the Mall
  80.     Minneapolis, Minnesota  55402
  81.  
  82.     612-375-3537
  83.  
  84.  
  85. BUGS:
  86.  
  87.     1. Does not support non-seekable devices (like pipes?)
  88.     2. Does not maintain the files original magic number, UID or GID.
  89.     3. May not handle garbage at the end of the archive terribly well.
  90.         (Our cpio puts an item called "TRAILER!!!" at the end, so fcpio
  91.         equates that with EOF as well as ending on EOF.  Other cpios
  92.         may behave differently....)
  93. SHAR_EOF
  94. fi
  95. if test -f 'fcpio.c'
  96. then
  97.     echo shar: "will not over-write existing file 'fcpio.c'"
  98. else
  99. cat << \SHAR_EOF > 'fcpio.c'
  100. #include <stdio.h>
  101. #include <sys/types.h>
  102. #include <fcntl.h>
  103. #include <errno.h>
  104. #include <dayton/math.h>
  105. #include <dayton/stdtyp.h>
  106.  
  107. /*
  108.  * fcpio - fast cpio for seek-able devices.
  109.  *
  110.  * Usage:
  111.  *
  112.  *        fcpio [-options] cpio-archive [extract-pattern-list]
  113.  *
  114.  * Implemented options are:
  115.  *
  116.  *        x - extract the named extract-pattern files.
  117.  *        t - print a table of contents.
  118.  *
  119.  * In extract mode, the extracted files are the ones whose names begin
  120.  *        with anything in the named list.  Skipped items are displayed
  121.  *        by a "." to indicate progress being made.
  122.  *
  123.  * Author:
  124.  *
  125.  *        Joe Larson
  126.  *        Dayton-Hudson Dept. Store Co.
  127.  *        700 On The Mall
  128.  *        Minneapolis, Minnesota 55402
  129.  *
  130.  *        UUCP:joe@dayton
  131.  */
  132.  
  133. struct Hdr
  134. {
  135.     short    h_magic,
  136.             h_dev;
  137.     ushort    h_ino,
  138.             h_mode,
  139.             h_uid,
  140.             h_gid,
  141.             h_nlink,
  142.             h_rdev,
  143.             h_mtime[2],
  144.             h_namesize,
  145.             h_filesize[2];
  146.     char    h_name[80];
  147. };
  148.  
  149. #define READBUFSIZE 100000
  150. char readbuf[READBUFSIZE];
  151.  
  152. main(argc,argv)
  153. int argc;
  154. char **argv;
  155. {
  156.     struct Hdr hstruct;        /* Indiv. file header in ifile.                */
  157.     int        ifile,            /* Archive file                                */
  158.             cur_pos,        /* Position in ifile                        */
  159.             fpos,            /* Another position in ifile                */
  160.             dummy,            /* Holds length of current file in ifile    */
  161.             i,                /* Counter for lots of things                */
  162.             ilens[20],        /* Lengths of x_names[].                    */
  163.             count,            /* # of files we've skipped.                */
  164.             x_count,        /* Number of x_names[].                        */
  165.             isize;            /* Used in seeking...                        */
  166.     char    *a_name,        /* Name of archive file                        */
  167.             *options,        /* Option string from cmnd line.            */
  168.             *x_names[20];    /* Name of extract file beginnings.            */
  169.     bool    do_extract,        /* Extract files?                            */
  170.             do_table,        /* Do a table of contents?                    */
  171.             x_here;            /* Extract this file?                        */
  172.  
  173.     a_name = NULL;
  174.     options = "x";
  175.     x_count = 0;
  176.     do_extract = 0;
  177.     do_table = 0;
  178.     for (i = 1; i < argc; i++)
  179.     {
  180.         if (*argv[i] == '-')
  181.             options = argv[i]+1;
  182.         else if (a_name == NULL)
  183.             a_name = argv[i];
  184.         else
  185.             x_names[x_count++] = argv[i];
  186.     }
  187.     if (a_name == NULL)
  188.     {
  189.         usage(argv[0]);
  190.         exit(0);
  191.     }
  192.     do_extract = (strchr(options, 'x') != NULL);
  193.     do_table = (strchr(options, 't') != NULL);
  194.     ifile = open(a_name, O_RDONLY);
  195.     if (ifile == -1)
  196.     {
  197.         perror(a_name);
  198.         exit(errno);
  199.     }
  200.     for (i = 0; i < x_count; i++)
  201.         ilens[i] = strlen(x_names[i]);
  202.     cur_pos = 0;
  203.     count = 0;
  204.     while(1)
  205.     {
  206.         if (read(ifile, &hstruct, sizeof(struct Hdr)) < sizeof(struct Hdr))
  207.             break;
  208.         if (!strcmp(hstruct.h_name, "TRAILER!!!"))
  209.             break;
  210.         dummy = (hstruct.h_filesize[0] << 16) + hstruct.h_filesize[1];
  211.         if (do_table)
  212.         {
  213.             fprintf(stderr, "%6ld %s\n", dummy, hstruct.h_name);
  214.             fflush(stderr);
  215.         }
  216.         isize = (hstruct.h_namesize + 1) & ~(1L);
  217.         if (do_extract)
  218.         {
  219.             x_here = !(x_count);    /* If no x_names, extract all */
  220.             for (i = 0; i < x_count; i++)
  221.                 if (!strncmp(x_names[i], hstruct.h_name, ilens[i]))
  222.                 {
  223.                     x_here = 1;
  224.                     break;
  225.                 }
  226.             if (x_here)
  227.             {
  228.                 if (count)
  229.                     fprintf(stderr, "\n");
  230.                 count = 0;
  231.                 fpos = cur_pos + sizeof(struct Hdr) - 80 + isize;
  232.                 fprintf(stderr, "X: %s", hstruct.h_name);
  233.                 fflush(stderr);
  234.                 copy_file(ifile, fpos, &hstruct, dummy);
  235.                 fprintf(stderr, ".\n");
  236.             }
  237.             else
  238.             {
  239.                 fprintf(stderr, ".");
  240.                 if (++count == 60)
  241.                 {
  242.                     fprintf(stderr, "\n");
  243.                     count = 0;
  244.                 }
  245.                 else
  246.                     fflush(stderr);
  247.             }
  248.         }
  249.         cur_pos += (dummy + sizeof(struct Hdr) - 80 + isize + 1) & ~(1L);
  250.         lseek(ifile, cur_pos, 0);
  251.     }
  252.     close(ifile);
  253. }
  254.  
  255.  
  256. copy_file(ifile, fpos, hstruct, ilen)
  257. int ifile, fpos, ilen;
  258. struct Hdr *hstruct;
  259. /*
  260.  * Copy out this file.  This routine still needs to do some things.
  261.  *
  262.  * For instance, no attempt is made to preserve the original files
  263.  *        magic number, c/m/a times, owner or group.
  264.  */
  265. {
  266.     int ofile, rlen, nlen;
  267.     char name[132], *c1, *c2;
  268.  
  269.     if (hstruct->h_mode & 0040000L)
  270.     {
  271.         make_path(hstruct->h_name, 1);
  272.         return;
  273.     }
  274.     for (c1 = NULL, c2=hstruct->h_name; *c2; c2++)
  275.         if (*c2 == '/')
  276.             c1 = c2;
  277.     if (c1 != NULL)
  278.     {
  279.         nlen = c1 - hstruct->h_name;
  280.         strncpy(name, hstruct->h_name, nlen);
  281.         name[nlen] = 0;
  282.         make_path(name, 1);
  283.     }
  284.     ofile = open(hstruct->h_name, O_WRONLY | O_CREAT, hstruct->h_mode&07777L);
  285.     if (ofile == -1)
  286.     {
  287.         perror(hstruct->h_name);
  288.         return;
  289.     }
  290.     lseek(ifile, fpos, 0L);
  291.     while (ilen > 0)
  292.     {
  293.         rlen = MIN(READBUFSIZE, ilen);
  294.         rlen = read(ifile, readbuf, rlen);
  295.         if (rlen > 0)
  296.             write(ofile, readbuf, rlen);
  297.         else
  298.             break;
  299.         ilen -= rlen;
  300.     }
  301.     close(ofile);
  302. }
  303.  
  304.  
  305.  
  306. usage(arg)
  307. char *arg;
  308. {
  309.     fprintf(stderr, "Usage: %s infilename\n", arg);
  310. }
  311.  
  312. make_path(p, flag)
  313. char *p, flag;
  314. /*
  315.  * Make sure this entire pathname exists.
  316.  */
  317. {
  318.     short ilen;
  319.     char name[132], *c1, *c2;
  320.  
  321.     if (access(p, 00))
  322.     {
  323.         if (flag)
  324.         {
  325.             for (c1 = NULL, c2 = p; *c2; c2++)
  326.             {
  327.                 if (*c2 == '/')
  328.                 {
  329.                     if (c1 != NULL)
  330.                     {
  331.                         ilen = c2 - p;
  332.                         strncpy(name, p, ilen);
  333.                         name[ilen] = 0;
  334.                         if (access(name, 00))
  335.                             make_path(p, 0);
  336.                     }
  337.                     c1 = c2;
  338.                 }
  339.             }
  340.         }
  341.         if (!fork())
  342.         {
  343.             execlp("mkdir", "mkdir", p, 0);
  344.             exit(errno);
  345.         }
  346.         else
  347.             wait(0);
  348.     }
  349. }
  350. SHAR_EOF
  351. fi
  352. if test -f 'math.h'
  353. then
  354.     echo shar: "will not over-write existing file 'math.h'"
  355. else
  356. cat << \SHAR_EOF > 'math.h'
  357. /*
  358.  * Dayton's math library definitions.
  359.  */
  360.  
  361. #define        MIN(x,y)    ((x < y) ? x : y)
  362. #define        MAX(x,y)    ((x > y) ? x : y)
  363. #define        ABS(x)        ((x < 0) ? -x : x)
  364. SHAR_EOF
  365. fi
  366. if test -f 'stdtyp.h'
  367. then
  368.     echo shar: "will not over-write existing file 'stdtyp.h'"
  369. else
  370. cat << \SHAR_EOF > 'stdtyp.h'
  371. /*
  372.  * Standard types and defines for Dayton-Hudson.
  373.  *
  374.  */
  375.  
  376. #include    <stdtyp.h>
  377.  
  378. #ifndef        TRUE
  379. #define        TRUE    (1)
  380. #endif
  381.  
  382. #ifndef        FALSE
  383. #define        FALSE    (0)
  384. #endif
  385.  
  386. #define ULONG unsigned long
  387. SHAR_EOF
  388. fi
  389. exit 0
  390. #    End of shell archive
  391.